package com.cgnpc.scp.sri.capacitybuilding.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IBpmCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.exception.ScpException;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.service.AppConstantService;
import com.cgnpc.scp.common.utils.MyPageResultUtil;
import com.cgnpc.scp.common.utils.StringUtil;
import com.cgnpc.scp.run.utils.CommonExportUtil;
import com.cgnpc.scp.sri.capacitybuilding.mybatis.entity.*;
import com.cgnpc.scp.sri.capacitybuilding.mybatis.mapper.client.CapacityBuildingInfoMapper;
import com.cgnpc.scp.sri.capacitybuilding.mybatis.mapper.client.CapacityBuildingPhaseProgressMapper;
import com.cgnpc.scp.sri.capacitybuilding.mybatis.mapper.client.CapacityPlanPhaseMapper;
import com.cgnpc.scp.sri.capacitybuilding.pojo.CapacityBuildingInfoVo;
import com.cgnpc.scp.sri.capacitybuilding.pojo.CapacityBuildingPhaseVo;
import com.cgnpc.scp.sri.capacitybuilding.service.CapacityBuildingService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service("capacityBuildingService")
public class CapacityBuildingServiceImpl implements CapacityBuildingService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CapacityBuildingServiceImpl.class);

    @Autowired
    IBpmCenterService bpmCenterService;

    @Autowired
    private CapacityBuildingInfoMapper capacityBuildingInfoMapper;

    @Autowired
    private CapacityPlanPhaseMapper capacityPlanPhaseMapper;

    @Autowired
    private CapacityBuildingPhaseProgressMapper capacityBuildingPhaseProgressMapper;

    @Autowired
    private CurrentUser currentUser;

    @Autowired
    private AppConstantService appConstantService;

    @Autowired
    private SqlSession sqlSession;

    @Override
    public MyPageResult<CapacityBuildingInfo> queryListPage(Map<String, Object> params) {
        MyPageResult<CapacityBuildingInfo> re = null;
        int pageNum = 1;
        int pageSize = 10;
        try {
            pageNum = Integer.parseInt(params.get("pageNum") + "");
            pageSize = Integer.parseInt(params.get("pageSize") + "");
        }catch (Exception e){
            e.printStackTrace();
        }
        Page<CapacityBuildingInfo> queryPage = PageHelper.startPage(pageNum, pageSize);
        capacityBuildingInfoMapper.listPage(params);
        PageInfo<CapacityBuildingInfo> pageResult = new PageInfo<>(queryPage.getResult());
        re = MyPageResultUtil.createMyPageResult(pageResult);

        return re;
    }

    @Override
    public CapacityBuildingInfoVo planInfo(String id) {
        List<CapacityPlanPhase> planList = capacityPlanPhaseMapper.selectList(new QueryWrapper<CapacityPlanPhase>()
        .select("*"
                , "(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_capacityplanphase.stage_result_file_id) as stage_result_file_name"
                , "(select file_center_url from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_capacityplanphase.stage_result_file_id) as stage_result_file_path")
        .eq("info_id", id));

        CapacityBuildingInfo info = capacityBuildingInfoMapper.planInfo(id);
        //wanzhiwe


        CapacityBuildingInfoVo vo = new CapacityBuildingInfoVo();
        vo.setCapacityBuildingInfo(info);
        vo.setCapacityPlanPhaseList(planList);
        return vo;
    }

    @Transactional
    @Override
    public AjaxResult planSave(Map<String, Object> params) throws Exception {
        Map<String, Object> win = (Map<String, Object>)params.remove("capaCity");
        win.remove("createTime");
        win.remove("lastUpdateTime");
        if(!StringUtil.isNullOrSpace(win.get("id")+"") && !"1".equals(params.get("isModifyDraft"))){
            String planId = win.remove("id")+"";
            win.put("infoId", planId);
        }
        CapacityBuildingInfo info = new CapacityBuildingInfo();
        BeanUtils.populate(info, win);
        info = saveOrUpdateInfo(info);
        List<Map<String, Object>> phaseMapList = (List<Map<String, Object>>) params.get("phases");
        List<CapacityPlanPhase> phases = new ArrayList<>();
        for(Map<String, Object> map : phaseMapList){
            CapacityPlanPhase phase = new CapacityPlanPhase();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("startTime", sdf.parse(map.remove("startTime")+""));
            map.put("endTime", sdf.parse(map.remove("endTime")+""));
            map.remove("createTime");
            map.remove("lastUpdateTime");
            BeanUtils.populate(phase, map);
            phases.add(phase);
        }
        saveOrUpdatePlanPhase(phases, info.getId());

        params.put("next_deal_name", JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        params.put("win", JSON.parseObject(JSON.toJSONString(win)));
        params.put("folio", info.getFolio());
        ApiResult apiResult = null;
        //判断是否为保存草稿
        params.put("appFormId", info.getId());
        if("1".equals(params.get("isSaveDraft"))){
            if(!"1".equals(params.get("isModifyDraft")+"")){
                bpmCenterService.addDraft(params);
            }
        }else{
            LOGGER.info("流程启动---");
            apiResult = bpmCenterService.startProcess(params);
            LOGGER.info("result--{}" , apiResult);
        }
        return AjaxResult.success().put("data", info);
    }

    /**********************************
     * 用途说明: 审批操作（通过或驳回）
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    @Transactional
    public ApiResult submitProcess(Map<String, Object> params) throws Exception {
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = params.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }
        //判断是前进还是后退
        String flag = params.get("deal_answer").toString();
        ApiResult apiResult = null;
        // 根据环节名称判断当前处理逻辑
        String act_name = params.get("now_deal_act").toString();
        String formInstID = params.get("formInstID").toString();
        params.put("next_deal_name",JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        Object copygive = params.remove("copygive");
        if(copygive != null && !"".equals(copygive)){
            params.put("copygive",JSONArray.parseArray(JSON.toJSONString(copygive)));
        }
        if (!StringUtil.isNullOrSpace(act_name)
                && ("020".equals(act_name) || "030".equals(act_name) || "040".equals(act_name) ||"010".equals(act_name))
        ) {
            if ("1".equals(flag)) {
                //提交
                if("true".equals(params.get("isEnd").toString())){
                    //提交且为最后一步 （此时需要将计划显示，若操作类型为变更，需要把计划变更信息覆盖到原计划）
//                Integer operateType = Integer.parseInt(params.get("operateType")+"");
                    CapacityBuildingInfo getOperateTypeInfo = capacityBuildingInfoMapper.selectOne(new QueryWrapper<CapacityBuildingInfo>()
                    .select("*","concat(project_name,'-', year) as plan_name")
                    .eq("id",formInstID));
                    Integer operateType = getOperateTypeInfo.getOperateType();
                    //操作类型,1:计划新增，2:计划信息变更
                    if(operateType == 1){
                        CapacityBuildingInfo info = new CapacityBuildingInfo();
                        info.setProcInstId(procInstId);
                        info.setProcessStatus("1");
                        info.setId(formInstID);
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        capacityBuildingInfoMapper.updateById(info);
                    }else if(operateType == 2){
                        //拿到更新的那条数据
                        CapacityBuildingInfo info = capacityBuildingInfoMapper.selectOne(new QueryWrapper<CapacityBuildingInfo>()
                                .select("*","concat(project_name,'-', year) as plan_name")
                                .eq("id",formInstID));
                        //把id改了，更新那条新增的计划
                        info.setId(info.getInfoId());
                        info.setOperateType(1);
                        info.setProcInstId(procInstId);
                        info.setProcessStatus("1");
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        capacityBuildingInfoMapper.updateById(info);
                    }else if(operateType == 3){
                        //若操作类型为关闭，需要更新其状态
                        CapacityBuildingInfo info = new CapacityBuildingInfo();
                        info.setId(formInstID);
                        info.setStatus("0");
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        capacityBuildingInfoMapper.updateById(info);
                    }
                }
                apiResult = bpmCenterService.submitworklistitem(params);
//                processAudit(params);
            } else if ("2".equals(flag)) {
                //驳回
                apiResult = bpmCenterService.rollBackAction(params);
            }
        } else {
            throw new ScpException("activity not found.");
        }
        return apiResult;
    }

    @Override
    public CapacityBuildingInfoVo planUpdate(CapacityBuildingInfoVo vo) {
        CapacityBuildingInfo info = saveOrUpdateInfo(vo.getCapacityBuildingInfo());
        saveOrUpdatePlanPhase(vo.getCapacityPlanPhaseList(), info.getId());
        vo.setCapacityBuildingInfo(info);
        return vo;
    }

    @Override
    public List<String> getAllYear() {
        return capacityBuildingInfoMapper.getAllYear();
    }

    private void saveOrUpdatePlanPhase(List<CapacityPlanPhase> phaseList, String infoId){
        if(phaseList == null || phaseList.size() == 0){
            return;
        }
        capacityPlanPhaseMapper.deleteByInfoId(infoId);
        UserInfo currentUserDetail = currentUser.getCurrentUserDetail();
        for(CapacityPlanPhase phase : phaseList){
            phase.setId(IDHelper.uuid());
            phase.setInfoId(infoId);
            Date date = new Date();
            phase.setCreateTime(date);
            phase.setCreateUser(currentUserDetail.getUserId());
            phase.setCreateUserName(currentUserDetail.getUserName());
            phase.setLastUpdateTime(date);
            phase.setLastUpdateUser(currentUserDetail.getUserId());
            phase.setLastUpdateUserName(currentUserDetail.getUserName());
            capacityPlanPhaseMapper.insert(phase);
        }
    }



    private CapacityBuildingInfo saveOrUpdateInfo(CapacityBuildingInfo capacityBuildingInfo) {

        Date date = new Date();
        UserInfo currentUserDetail = currentUser.getCurrentUserDetail();
        capacityBuildingInfo.setLastUpdateTime(date);
        capacityBuildingInfo.setLastUpdateUser(currentUserDetail.getUserId());
        capacityBuildingInfo.setLastUpdateUserName(currentUserDetail.getUserName());
        if(StringUtil.isNullOrSpace(capacityBuildingInfo.getId())){
            //新增
            capacityBuildingInfo.setId(IDHelper.uuid());
            capacityBuildingInfo.setCreateTime(date);
            capacityBuildingInfo.setCreateUser(currentUserDetail.getUserId());
            capacityBuildingInfo.setCreateUserName(currentUserDetail.getUserName());
            String folio = capacityBuildingInfo.getProcessName() + "-" + capacityBuildingInfo.getCreateUser() + "-" +
                    new SimpleDateFormat("yyyyMMdd").format(capacityBuildingInfo.getCreateTime());
            capacityBuildingInfo.setFolio(folio);
            capacityBuildingInfo.setProcessStatus("0");
            capacityBuildingInfo.setStatus("1");
            capacityBuildingInfoMapper.insert(capacityBuildingInfo);
        }else{
            //更新
            capacityBuildingInfoMapper.updateById(capacityBuildingInfo);
        }
        return capacityBuildingInfo;
    }

    @Override
    public CreateFileInfo exportExcel(Map<String, Object> params) throws Exception {
        CreateFileInfo createFileInfo;

        try {
            List<String> titleList = Arrays.asList(
                    "计划名称","能力建设项目名称","年度"
                    ,"负责人","状态","计划提交人","计划提交日期","审批完成日期"
            );
            List<String> fields = Arrays.asList("planName","projectName", "year"
                    ,"leadingmanName","sriStatus","createUserName","createTime","lastUpdateTime"
            );

            CommonExportUtil<CapacityBuildingInfo> util = new CommonExportUtil<>();
            createFileInfo = util.exportExcel(appConstantService, sqlSession, titleList, fields
                    , "com.cgnpc.scp.sri.capacitybuilding.mybatis.mapper.client.CapacityBuildingInfoMapper"
                    ,"listPageExport", params);
        } catch (Exception e) {
            throw e;
        }

        return createFileInfo;
    }


    @Override
    public List<CapacityBuildingInfo> getAllPlanInfo() {
        return capacityBuildingInfoMapper.selectList(new QueryWrapper<CapacityBuildingInfo>()
        .select("*","concat(project_name,'-', year) as plan_name")
        //审核通过的
        .eq("process_status","1")
         //计划新增的
        .eq("operate_type","1"));
    }

    @Override
    public List<CapacityPlanPhase> getPhaseByPlanId(String planId) {
        return capacityPlanPhaseMapper.selectList(new QueryWrapper<CapacityPlanPhase>()
        .select("*","(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = stage_result_file_id) as stage_result_file_name")
        .eq("info_id",planId));
    }

    @Transactional
    @Override
    public AjaxResult planStageSave(Map<String, Object> params) throws Exception {
        Map<String, Object> win = (Map<String, Object>)params.remove("stage");
        String phaseId = win.get("phaseId")+"";
        if(StringUtil.isNullOrSpace(phaseId) || "null".equals(phaseId)){
            return AjaxResult.error("phaseId can not be null");
        }
        CapacityPlanPhase capacityPlanPhase = capacityPlanPhaseMapper.selectOne(new QueryWrapper<CapacityPlanPhase>()
        .select("*","(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = stage_result_file_id) as stage_result_file_name")
        .eq("id",phaseId));
        CapacityBuildingPhaseProgress progress = new CapacityBuildingPhaseProgress();
        String stageResultFileId = win.get("stageResultFileId")+"";
        String stageProgress = win.get("stageProgress")+"";
        progress.setStageProgress(stageProgress);
        progress.setStageResultFileId(stageResultFileId);
        if("1".equals(params.get("isModifyDraft"))){
            //修改草稿的情况
            capacityBuildingPhaseProgressMapper.update(progress, new UpdateWrapper<CapacityBuildingPhaseProgress>()
                    .eq("phase_id", phaseId));
            return AjaxResult.success().put("data", capacityPlanPhase);
        }
        progress.setId(IDHelper.uuid());
        progress.setPhaseId(capacityPlanPhase.getId());
        progress.setProcessStatus("0");
        capacityBuildingPhaseProgressMapper.insert(progress);
        String folio = params.get("procChName") + "-" + capacityPlanPhase.getCreateUser() + "-" +
                new SimpleDateFormat("yyyyMMdd").format(capacityPlanPhase.getCreateTime());
        capacityPlanPhase.setFolio(folio);
        capacityPlanPhaseMapper.updateById(capacityPlanPhase);

        params.put("next_deal_name", JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        params.put("win", JSON.parseObject(JSON.toJSONString(win)));
        params.put("folio", folio);
        ApiResult apiResult = null;
        //判断是否为保存草稿
        params.put("appFormId", progress.getId());
        if("1".equals(params.get("isSaveDraft"))){
            if(!"1".equals(params.get("isModifyDraft")+"")){
                bpmCenterService.addDraft(params);
            }
        }else{
            LOGGER.info("流程启动---");
            apiResult = bpmCenterService.startProcess(params);
            LOGGER.info("result--{}" , apiResult);
        }
        return AjaxResult.success().put("data", capacityPlanPhase);
    }

    /**********************************
     * 用途说明: 进展提交流程的审批操作（通过或驳回）
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    @Transactional
    public ApiResult stageSubmitProcess(Map<String, Object> params) throws Exception {
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = params.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }
        //判断是前进还是后退
        String flag = params.get("deal_answer").toString();
        ApiResult apiResult = null;
        // 根据环节名称判断当前处理逻辑
        String act_name = params.get("now_deal_act").toString();
        String formInstID = params.get("formInstID").toString();
        params.put("next_deal_name",JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        Object copygive = params.remove("copygive");
        if(copygive != null && !"".equals(copygive)){
            params.put("copygive",JSONArray.parseArray(JSON.toJSONString(copygive)));
        }
        if (!StringUtil.isNullOrSpace(act_name)
                && ("020".equals(act_name) ||"010".equals(act_name))
        ) {
            CapacityBuildingPhaseProgress progress = capacityBuildingPhaseProgressMapper.selectOne(new QueryWrapper<CapacityBuildingPhaseProgress>()
            .select("*","(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_phase_progress.stage_result_file_id) as stage_result_file_name")
            .eq("id",formInstID));
            progress.setProcInstId(procInstId);
            if ("1".equals(flag)) {
                if("020".equals(act_name)){
                    //最后一个环节
                    progress.setProcessStatus("1");
                    progress.setProcessFinalTime(new Date());

                    CapacityPlanPhase phase = capacityPlanPhaseMapper.selectById(progress.getPhaseId());
                    phase.setStageProgress(progress.getStageProgress());
                    phase.setStageResultFileId(progress.getStageResultFileId());
                    capacityPlanPhaseMapper.updateById(phase);
                }
                //提交
                apiResult = bpmCenterService.submitworklistitem(params);
            } else if ("2".equals(flag)) {
                //驳回
                apiResult = bpmCenterService.rollBackAction(params);
            }
            capacityBuildingPhaseProgressMapper.updateById(progress);
        } else {
            throw new ScpException("activity not found.");
        }
        return apiResult;
    }

    @Override
    public CapacityBuildingPhaseVo stageInfo(String id) {
        CapacityPlanPhase phase = capacityPlanPhaseMapper.selectOne(new QueryWrapper<CapacityPlanPhase>()
        .select("*"
                ,"(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_capacityplanphase.stage_result_file_id) as stage_result_file_name"
                ,"(select file_center_url from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_capacityplanphase.stage_result_file_id) as stage_result_file_path")
        .eq("id",id));

        CapacityBuildingPhaseVo vo = new CapacityBuildingPhaseVo();
        vo.setPhase(phase);

        CapacityBuildingInfo info = capacityBuildingInfoMapper.selectOne(new QueryWrapper<CapacityBuildingInfo>()
        .select("*","concat(project_name,'-', year) as plan_name")
        .eq("id",phase.getInfoId()));
        vo.setCapaCity(info);
        return vo;
    }

    @Override
    public CapacityBuildingPhaseVo progressInfo(String id) {
        CapacityBuildingPhaseProgress progress = capacityBuildingPhaseProgressMapper.selectOne(new QueryWrapper<CapacityBuildingPhaseProgress>()
                .select("*","(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_capacitybuilding_phase_progress.stage_result_file_id) as stage_result_file_name")
                .eq("id",id));
        CapacityBuildingPhaseVo vo = stageInfo(progress.getPhaseId());
        vo.setProgress(progress);

        return vo;
    }

    @Override
    public ApiResult deleteDraft(Map<String, Object> params) throws Exception {
        String infoId = params.get("formno").toString();
        capacityPlanPhaseMapper.deleteByInfoId(infoId);
//        capacityBuildingInfoMapper.selectOne(new QueryWrapper<CapacityBuildingInfo>()
//                .select("*","concat(project_name,'-', year) as plan_name")
//                .eq("id",infoId));
        capacityBuildingInfoMapper.deleteById(infoId);

        return bpmCenterService.deleteMyDraft(params);
    }

    @Override
    public ApiResult deleteProcessDraft(Map<String, Object> params) throws Exception {
        String infoId = params.get("formno").toString();

        capacityBuildingPhaseProgressMapper.deleteById(infoId);

        return bpmCenterService.deleteMyDraft(params);
    }
}
